package org.tote.dao;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.tote.exception.NoSuchDaoAvailableException;
import org.tote.model.MailMessageTemplate;
import org.tote.model.MailMessageType;
import org.tote.model.Role;
import org.tote.model.User;
import org.tote.model.UserLight;

/**
 * Provides an access to various DAO implementations.
 * 
 */
@Component
public class DaoFacadeImpl implements DaoFacade {

	@Autowired
	private UserDao userDao;

	@Autowired
	private UserLightDao userLightDao;

	@Autowired
	private RoleDao roleDao;

	@Autowired
	private MailMessageDao mailMessageDao;

	private Map<Class<?>, BasicCrudDao<?, ?>> daos;

	@SuppressWarnings("unused")
	@PostConstruct
	private void init() {
		daos = new HashMap<Class<?>, BasicCrudDao<?, ?>>();
		daos.put(MailMessageTemplate.class, mailMessageDao);
		daos.put(User.class, userDao);
		//daos.put(UserLight.class, userLightDao);
		daos.put(Role.class, roleDao);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public <T> void save(T entity) throws NoSuchDaoAvailableException {
		BasicCrudDao dao = daos.get(entity.getClass());
		if (dao == null) {
			throw new NoSuchDaoAvailableException();
		} else {
			dao.save(entity);
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public <T> void update(T entity) throws NoSuchDaoAvailableException {
		BasicCrudDao dao = daos.get(entity.getClass());
		if (dao == null) {
			throw new NoSuchDaoAvailableException();
		} else {
			dao.update(entity);
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public <T> void remove(T entity) throws NoSuchDaoAvailableException {
		BasicCrudDao dao = daos.get(entity.getClass());
		if (dao == null) {
			throw new NoSuchDaoAvailableException();
		} else {
			dao.remove(entity);
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public <T, I> T getById(I id, Class<T> clazz) {
		BasicCrudDao dao = daos.get(clazz);
		if (dao == null) {
			throw new NoSuchDaoAvailableException();
		} else {
			return (T) dao.getById(id);
		}
	}

	public MailMessageTemplate getMailMessageTemplateById(MailMessageType mailMessageType) {
		return mailMessageDao.getById(mailMessageType);
	}

	public User getUserById(Long userId) {
		return userDao.getById(userId);
	}

	public UserLight getUserLightById(Long userId) {
		return userLightDao.getById(userId);
	}

	public UserDao getUserDao() {
		return userDao;
	}

	public UserLightDao getUserLightDao() {
		return userLightDao;
	}

	public MailMessageDao getMailMessageDao() {
		return mailMessageDao;
	}

	@Override
	public RoleDao getRoleDao() {
		return roleDao;
	}
}
